package util.ndl.v1

import java.sql.{DriverManager, ResultSet}

import grpc.v1.rpcV1._
import io.grpc.stub.StreamObserver
import org.testng.annotations.{BeforeClass, Test}
import ws.very.util.lang.Using

import scala.concurrent.ExecutionContext

class TestRpc extends SchemaDataGrpc.SchemaData {
  val datas = (1 to 10).map { i =>
    import ColValue._
    import Of._
    RowData((StringValue("t1-" + i) :: StringValue("t2-" + i * 2) :: DoubleValue(1.37d*i) :: Int32Value(i) :: Nil).map {
      ColValue(_)
    })


  }

  override def getTableInfos(request: GetTableInfosReq, responseObserver: StreamObserver[Tbl]): U = {
    /**
      *     fieldBuilder.add("T1", SqlTypeName.VARCHAR) //
      *     fieldBuilder.add("T2", SqlTypeName.VARCHAR)
      *     fieldBuilder.add("T3", SqlTypeName.DECIMAL)
      */
    responseObserver.onNext(Tbl("tbl", Col("t1", SqlTypeName.VARCHAR) ::
      Col("T2", SqlTypeName.VARCHAR) :: Col("t3", SqlTypeName.DECIMAL) ::Col("T4",SqlTypeName.INTEGER) :: Nil))
    responseObserver.onCompleted()

  }

  override def scan(request: ScanReq, responseObserver: StreamObserver[RowData]): U = {
    datas.foreach { row =>

      responseObserver.onNext(row)
    }

    responseObserver.onCompleted()
  }
}
class Testwork extends gRPCServer {



  @BeforeClass
  def startRpcServer = {
    val service = SchemaDataGrpc.bindService(new TestRpc, ExecutionContext.global)
    runServer(service)
  }


  @Test(enabled = false)
  def testSql =
    fluent(model(), "select * from tbl where t1='123' and t2 like '2%' or t3<=3", {})

  @Test
  def testSql2 =
    fluent(model(), "select * from tbl where t1='123' and (t2 like '2%' or t3<=3) and (t3 in (1,2,3) or t3 between 1 and 3)", { rs =>

      while (rs.next()) {
        println(s"${rs.getString("t1")} ${rs.getString("t2")}  ${rs.getInt("t3")}")
      }

    })

  @Test
  def testIntDev =
    fluent(model(), "select * from tbl where t4 / 2 =1", { rs =>

      while (rs.next()) {
        println(s"${rs.getString("t1")} ${rs.getString("t2")}  ${rs.getInt("t3")}   ${rs.getInt("t4")}")
      }

    })

  @Test(enabled = false)
  def testIntMod =
    fluent(model(), "select * from tbl where t4 % 2 =1", { rs =>

      while (rs.next()) {
        println(s"${rs.getString("t1")} ${rs.getString("t2")}  ${rs.getDouble("t3")} ${rs.getInt("t4")}")
      }

    })

  val clazz = "util.ndl.v1.GrpcSchemaFactory"

  def model(clazz: S = clazz) =
    s"""{
       |  "version": "1.0",
       |  "defaultSchema": "schema",
       |  "schemas": [
       |    {
       |      "name": "schema",
       |      "type": "custom",
       |      "factory": "$clazz",
       |      "operand": {
       |      }
       |    }
       |  ]
       |}
       |""".stripMargin

  def fluent[R](model: S, sql: S, fn: ResultSet => R = { rs: ResultSet => null }) = Using {
    val connection = DriverManager.getConnection("jdbc:calcite:lex=MYSQL;unquotedCasing=UNCHANGED;model=inline:" + model)
    val statement = connection.createStatement

    (statement, connection)
  } { case (statement, connection) =>
    fn(statement.executeQuery(sql))
  }


}